﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace LeanEngine.Business
{
    public abstract class DiagnosticCategoryItem
    {
        #region Constructor

        /// <summary>
        /// Default constructor for LeanEngine.Business.DiagnosticCategoryItem class.
        /// </summary>
        /// <param name="category">The application counter category.</param>
        public DiagnosticCategoryItem(DiagnosticCategory category)
        {
            this.Category = category;
        }

        #endregion

        #region PropertyInfo Members

        /// <summary>
        /// Gets the application performance counter category.
        /// </summary>
        protected DiagnosticCategory Category { get; private set; }

        /// <summary>
        /// Gets the counter name.
        /// </summary>
        public abstract string Name { get; }

        /// <summary>
        /// Gets the helper description.
        /// </summary>
        public abstract string Description { get; }

        /// <summary>
        /// Gets the specified formula used to calculate the System.Diagnostics.PerformanceConter.NextValue() method.
        /// </summary>
        public abstract PerformanceCounterType CounterType { get; }

        #endregion

        #region Method Members

        /// <summary>
        /// Calculates the next value fot this counter.
        /// </summary>
        protected abstract long NextValue();

        /// <summary>
        /// Increments the associated performance counter by one through an efficient and thread-safe operation.
        /// </summary>
        /// <param name="value">The new value for the counter.</param>
        public void Increment()
        {
            if (DiagnosticCategory.Exists(this.Category))
            {
                using (var counter = new PerformanceCounter(Category.CategoryName, this.Name, false))
                {
                    lock (counter)
                    {
                        counter.RawValue = this.NextValue();
                    }
                }
            }
        }

        #endregion
    }
}
